﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WI.CandidateManager.Common.Data.Entities;

namespace WI.CandidateManager.Business.Objects
{
    /// <summary>
    /// Logic for working with Courseworks: creating, editing, deleting etc.
    /// </summary>
    public class CourseworkBO : BOBase
    {
        #region Coursework logic

        /// <summary>
        /// Getting list of own Courseworks.
        /// </summary>
        /// <returns>List of own Courseworks.</returns>
        public List<Coursework> GetCourseworkList()
        {
            try
            {
                if (Session.User.Role == Common.Data.Enums.UserRole.Coach || Session.User.Role == Common.Data.Enums.UserRole.Admin)
                {
                    var list = DataContext.CourseworkSet.Where(c => c.Owner.Id == Session.User.Id && c.State == Common.Data.Enums.State.Active).ToList<Coursework>();
                    Logger.Info(String.Format("Try to get list of own courseworks from DB"));
                    return list;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to get list of own courseworks from DB"), ex);
                return new List<Coursework>();
            }
        }

        /// <summary>
        /// Getting list of all Courseworks.
        /// </summary>
        /// <returns>List of all Courseworks.</returns>
        public List<Coursework> GetAllCourseworkList()
        {
            try
            {
                if (Session.User.Role == Common.Data.Enums.UserRole.Coach || Session.User.Role == Common.Data.Enums.UserRole.Admin)
                {
                    var list = DataContext.CourseworkSet.Where(c => c.State == Common.Data.Enums.State.Active).ToList<Coursework>();
                    Logger.Info(String.Format("Try to get list of all courseworks from DB"));
                    return list;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to get list of all courseworks from DB"), ex);
                return new List<Coursework>();
            }
        }

        /// <summary>
        /// Getting list of Pending Courseworks.
        /// </summary>
        /// <returns>List of Pending Courseworks.</returns>
        public List<Coursework> GetPendingCourseworkList()
        {
            try
            {
                var coach = DataContext.CoachSet.Single(c => c.Id == Session.User.Id);

                if (coach.Role == Common.Data.Enums.UserRole.Coach)
                {

                    var list = DataContext.CourseworkSet.Where(c => c.ResultBase.Any(r => r.Status == Common.Data.Enums.TaskState.Completed
                        && r.Candidate.StudyGroup.Any(g => g.Couch.Any(co => co.Id == coach.Id))
                        && r.State == Common.Data.Enums.State.Active) && c.State == Common.Data.Enums.State.Active).ToList<Coursework>();

                    Logger.Info(String.Format("Try to get list of pending courseworks from DB"));
                    return list;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to get list of pending courseworks from DB"), ex);
                return new List<Coursework>();
            }
        }


        /// <summary>
        /// Get object of Coursework.
        /// </summary>
        /// <param name="CourseworkId">Coursework id.</param>
        /// <returns>Object of Coursework.</returns>
        public Coursework GetCoursework(long CourseworkId)
        {
            try
            {
                var coursework = DataContext.CourseworkSet.Single(c => c.Id == CourseworkId);
                Logger.Info(String.Format("Try to get coursework by CourseworkId={0} from DB", CourseworkId));
                return coursework;
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to get coursework by CourseworkId={0} from DB", CourseworkId), ex);
                return null;
            }
        }

        /// <summary>
        /// Create new Coursework and add it to DataBase.
        /// </summary>
        /// <param name="coursework">Object of Coursework from controller.</param>
        /// <returns>True if creating was succesful and false if it wasn't.</returns>
        public bool CreateNewCoursework(Coursework coursework)
        {
            try
            {
                var curUser = DataContext.CoachSet.Where(c => c.Id == Session.User.Id).Single();

                if (curUser.Role == Common.Data.Enums.UserRole.Coach || curUser.Role == Common.Data.Enums.UserRole.Admin)
                {
                    coursework.Owner = curUser;
                    coursework.CreateDate = System.DateTime.Now;

                    DataContext.CourseworkSet.Add(coursework);
                    DataContext.SaveChanges();
                    Logger.Info(String.Format("Try to create new coursework in DB"));
                    return true;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to create new coursework in DB"), ex);
                return false;
            }
        }

        /// <summary>
        /// Change object of Coursework.
        /// </summary>
        /// <param name="CourseworkkId">Coursework id.</param>
        /// <param name="coursework">Object of Coursework.</param>
        /// <returns>True if editing was succesful and false if it wasn't.</returns>
        public bool ChangeCoursework(long CourseworkId, Coursework coursework)
        {
            try
            {
                var curCoursework = DataContext.CourseworkSet.Where(c => c.Id == CourseworkId).Single();

                if (curCoursework.Owner.Id == Session.User.Id || Session.User.Role == Common.Data.Enums.UserRole.Admin)
                {

                    curCoursework.Name = coursework.Name;
                    curCoursework.Description = coursework.Description;
                    curCoursework.State = coursework.State;

                    DataContext.Entry(curCoursework).State = System.Data.EntityState.Modified;
                    Logger.Info(String.Format("Try to change coursework (CourseworkId={0}) in DB", CourseworkId));
                    DataContext.SaveChanges();
                    return true;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to change coursework (CourseworkId={0}) in DB", CourseworkId), ex);
                return false;
            }
        }

        /// <summary>
        /// Delete object of Coursework.
        /// </summary>
        /// <param name="CourseworkId">Coursework id.</param>
        /// <returns>True if deleting was succesful and false if it wasn't.</returns>
        public bool DeleteCoursework(long CourseworkId)
        {
            try
            {
                var coursework = DataContext.CourseworkSet.Single(c => c.Id == CourseworkId);

                if (coursework.Owner.Id == Session.User.Id || Session.User.Role == Common.Data.Enums.UserRole.Admin)
                {
                    coursework.State = Common.Data.Enums.State.Deleted;
                    DataContext.SaveChanges();
                    Logger.Info(String.Format("Try to delete coursework (CourseworkId={0}) from DB", CourseworkId));

                    return true;
                }
                else
                {
                    throw new Exception("Attempt of unauthorized access.");
                }
            }
            catch (Exception ex)
            {
                Logger.Error(String.Format("Unable to delete coursework (CourseworkId={0}) from DB", CourseworkId), ex);
                return false;
            }
        }

        #endregion
    }
}
